home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gnu / adainc / s-tasuti.ads < prev    next >
Text File  |  1996-01-30  |  23KB  |  515 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                 GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS               --
  4. --                                                                          --
  5. --              S Y S T E M . T A S K I N G . U T I L I T I E S             --
  6. --                                                                          --
  7. --                                  S p e c                                 --
  8. --                                                                          --
  9. --                             $Revision: 1.10 $                             --
  10. --                                                                          --
  11. --       Copyright (c) 1991,1992,1993,1994, FSU, All Rights Reserved        --
  12. --                                                                          --
  13. -- GNARL is free software; you can redistribute it  and/or modify it  under --
  14. -- terms  of  the  GNU  Library General Public License  as published by the --
  15. -- Free Software  Foundation;  either version 2, or (at  your  option)  any --
  16. -- later  version.  GNARL is distributed  in the hope that  it will be use- --
  17. -- ful, but but WITHOUT ANY WARRANTY;  without even the implied warranty of --
  18. -- MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Gen- --
  19. -- eral Library Public License  for more details.  You should have received --
  20. -- a  copy of the GNU Library General Public License along with GNARL;  see --
  21. -- file COPYING.LIB.  If not,  write to the  Free Software Foundation,  675 --
  22. -- Mass Ave, Cambridge, MA 02139, USA.                                      --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. --  This package provides RTS Internal Declarations.
  27. --  These declarations are not part of the GNARLI
  28.  
  29. with Unchecked_Conversion;
  30.  
  31. with System.Compiler_Exceptions;
  32. --  Used for, Exception_ID
  33.  
  34. package System.Tasking.Utilities is
  35.  
  36.    --  Entry queue related types
  37.  
  38.    type Server_Kind is (Task_Server, PO_Server);
  39.  
  40.    type Server_Record (Kind : Server_Kind := Task_Server) is record
  41.       case Kind is
  42.          when Task_Server =>
  43.             Called_Task : Task_ID;
  44.             Acceptor_Prev_Call : Entry_Call_Link;
  45.  
  46.             Acceptor_Prev_Priority : Rendezvous_Priority;
  47.             --  For a task servicing a task entry call,
  48.             --  information about the most recent prior call being serviced.
  49.             --   Not used for protected entry calls;
  50.             --  this function should be performed by GNULLI ceiling locking.
  51.  
  52.          when PO_Server =>
  53.             Called_PO : Protection_Access;
  54.  
  55.       end case;
  56.    end record;
  57.  
  58.    --  Protected Objects related definitions
  59.  
  60.    Null_PO : constant Protection_Access := null;
  61.  
  62.    --  ATCB type definitions
  63.  
  64.  
  65.    type Ada_Task_Control_Block (Entry_Num : Task_Entry_Index);
  66.  
  67.    type ATCB_Ptr is access Ada_Task_Control_Block;
  68.  
  69.    All_Tasks_List : ATCB_Ptr;
  70.    All_Tasks_L : Task_Primitives.Lock;
  71.  
  72.    function ID_To_ATCB is new
  73.      Unchecked_Conversion (Task_ID, ATCB_Ptr);
  74.  
  75.    function ATCB_To_ID is new
  76.      Unchecked_Conversion (ATCB_Ptr, Task_ID);
  77.  
  78.    function ATCB_To_Address is new
  79.      Unchecked_Conversion (ATCB_Ptr, System.Address);
  80.  
  81.    type Task_Stage is (
  82.       Created,
  83.       --  Task has been created but has not begun activation.
  84.  
  85.       Can_Activate,
  86.       --  Task has begin activation.
  87.  
  88.       Active,
  89.       --  Task has completed activation and is executing the task body.
  90.  
  91.       Await_Dependents,
  92.       --  Task is trying to complete a task master other than itself,
  93.       --  and is waiting for the tasks dependent on that master to become
  94.       --  passive (be complete, terminated, or be waiting on a terminate
  95.       --  alternative).
  96.  
  97.       Passive,
  98.       --  The task is passive.
  99.  
  100.       Completing,
  101.       --  The task is committed to becoming complete, but has not yet
  102.       --  satisfied all of the conditions for completion.  This
  103.       --  acts as a claim to completion; once Stage is set to this value,
  104.       --  no other task can continue with completion.
  105.  
  106.       Complete,
  107.       --  The task is complete.  The task and all of its dependents are
  108.       --  passive; some dependents may still be waiting on terminate
  109.       --  alternatives.
  110.  
  111.       Terminated);
  112.       --  The task is terminated.  All dependents waiting on terminate
  113.       --  alternatives have been awakened and have terminated themselves.
  114.  
  115.    type Accepting_State is (
  116.       Not_Accepting,   --  task is not ready to accept any entry call
  117.       Trivial_Accept,   --  "accept E;"
  118.       Simple_Accept,    --  "accept E do ... end E;"
  119.       Select_Wait);     --  most general case
  120.  
  121.    type Entry_Call_Array is array (ATC_Level_Index) of
  122.      aliased Entry_Call_Record;
  123.  
  124.    type Entry_Queue_Array is array (Task_Entry_Index range <>) of Entry_Queue;
  125.  
  126.    --  Alignment problems: Data types used by Pthreads (e.g. lock "L")
  127.    --  need to be word aligned. Do NOT place any non-aligned record
  128.    --  members before the members that need alignment or Pthreads will
  129.    --  break. Right now, anything up to "Rend_Cond" may need word alignment.
  130.    --  This is due to code generated by the C compiler and will
  131.    --  be an issue for any C/Ada interface.
  132.  
  133.    --  Notes on protection (synchronization) of TRTS data structures.
  134.  
  135.    --  Any field of the TCB can be written by the activator of a task when the
  136.    --  task is created, since no other task can access the new task's
  137.    --  state until creation is complete.
  138.  
  139.    --  The protection for each field is described in a comment starting with
  140.    --  "Protection:".
  141.  
  142.    --  When a lock is used to protect an ATCB field, this lock is simply named.
  143.  
  144.    --  Some protection is described in terms of tasks related to the
  145.    --  ATCB being protected.  These are:
  146.  
  147.    --    Self: The task which is controlled by this ATCB.
  148.    --    Acceptor: A task accepting a call from Self.
  149.    --    Caller: A task calling an entry of Self.
  150.    --    Parent: The task executing the master on which Self depends.
  151.    --    Dependent: A task dependent on Self.
  152.    --    Activator: The task that created Self and initiated its activation.
  153.    --    Created: A task created and activated by Self.
  154.  
  155.    type Ada_Task_Control_Block (Entry_Num : Task_Entry_Index) is record
  156.  
  157.       LL_TCB : aliased Task_Primitives.Task_Control_Block;
  158.       --  Control block used by the underlying low-level tasking service
  159.       --  (GNULLI).
  160.       --  Protection: This is used only by the GNULLI implementation, which
  161.       --  takes care of all of its synchronization.
  162.  
  163.       Task_Entry_Point : Task_Procedure_Access;
  164.       --  Information needed to call the procedure containing the code for
  165.       --  the body of this task.
  166.       --  Protection: Part of the synchronization between Self and
  167.       --  Activator.  Activator writes it, once, before Self starts
  168.       --  executing.  Self reads it, once, as part of its execution.
  169.  
  170.       Task_Arg : System.Address;
  171.       --  The argument to to task procedure.  Currently unused; this will
  172.       --  provide a handle for discriminant information.
  173.       --  Protection: Part of the synchronization between Self and
  174.       --  Activator.  Activator writes it, once, before Self starts
  175.       --  executing.  Thereafter, Self only reads it.
  176.  
  177.       Stack_Size : Size_Type;
  178.       --  Requested stack size.
  179.       --  Protection: Only used by Self.
  180.  
  181.       Current_Priority : System.Priority;
  182.       --  Active priority, except that the effects of protected object
  183.       --  priority ceilings are not reflected.  This only reflects explicit
  184.       --  priority changes and priority inherited through task activation
  185.       --  and rendezvous.
  186.       --  Ada 9X notes: In Ada 9X, this field will be transferred to the
  187.       --  Priority field of an Entry_Calls component when an entry call
  188.       --  is initiated.  The Priority of the Entry_Calls component will not
  189.       --  change for the duration of the call.  The accepting task can
  190.       --  use it to boost its own priority without fear of its changing in
  191.       --  the meantime.
  192.       --  This can safely be used in the priority ordering
  193.       --  of entry queues.  Once a call is queued, its priority does not
  194.       --  change.
  195.       --  Since an entry call cannot be made while executing
  196.       --  a protected action, the priority of a task will never reflect a
  197.       --  priority ceiling change at the point of an entry call.
  198.       --  Protection: Only written by Self, and only accessed when Acceptor
  199.       --  accepts an entry or when Created activates, at which points Self is
  200.       --  suspended.
  201.  
  202.       Base_Priority : System.Priority;
  203.       --  Base priority, not changed during entry calls, only changed
  204.       --  via dynamic priorities package.
  205.       --  Protection: Only written by Self, accessed by anyone.
  206.  
  207.       New_Base_Priority : System.Priority;
  208.       --  New value for Base_Priority (for dynamic priorities package).
  209.       --  Protection: Self.L.
  210.  
  211.       L : Task_Primitives.Lock;
  212.       --  General purpose lock; protects most fields in the ATCB.
  213.  
  214.       Compiler_Data : System.Address;
  215.       --  Untyped task-specific data needed by the compiler to store
  216.       --  per-task structures.
  217.       --  Protection: Only accessed by Self.
  218.  
  219.       --  the following declarations are for Rendezvous
  220.  
  221.       Cond : Task_Primitives.Condition_Variable;
  222.       Rend_Cond : Task_Primitives.Condition_Variable;
  223.       --  Rend_Cond is used by the task owning this ATCB for waits involved in
  224.       --  rendezvous, and Cond is used for all other waits.  There is currently
  225.       --  no overlap in the use of these condition variables; see comment to
  226.       --  Abort_Tasks in Task_Stages.
  227.       --  Protection: Condition variables are always associated with a lock.
  228.       --  The runtime places no restrictions on which lock is used, except
  229.       --  that it must protection the condition opon which the task is waiting.
  230.       --  Currently, Cond is always associated with Self.L, and Rend_Cond
  231.       --  is always associated with Acceptor.L.
  232.  
  233.       All_Tasks_Link : ATCB_Ptr;
  234.       --  Used to link this task to the list of all tasks in the system.
  235.       --  Protection: All_Tasks.L.
  236.  
  237.       Activation_Link : ATCB_Ptr;
  238.       --  Used to link this task to a list of tasks to be activated.
  239.       --  Protection: Only used by Activator.
  240.  
  241.       Open_Accepts : Accept_List_Access;
  242.       --  This points to the Open_Accepts array of accept alternatives passed
  243.       --  to the RTS by the compiler-generated code to Selective_Wait.
  244.       --  Protection: Self.L.
  245.  
  246.       Exception_To_Raise : Compiler_Exceptions.Exception_ID;
  247.       Exception_Address : System.Address;
  248.       --  An exception which should be raised by this task when it regains
  249.       --  control, and the address at which it should be raised.
  250.       --  Protection: Read only by Self, under circumstances where it will
  251.       --  be notified by the writer when it is safe to read it:
  252.       --  1. Written by Acceptor, when Self is suspended.
  253.       --  2. Written by Notify_Exception, executed by Self through a
  254.       --     synchronous signal handler, which redirects control to a
  255.       --     routine to read it and raise the exception.
  256.  
  257.       Chosen_Index : Select_Index;
  258.       --  The index in Open_Accepts of the entry call accepted by a selective
  259.       --  wait executed by this task.
  260.       --  Protection: Written by both Self and Caller.  Usually protected
  261.       --  by Self.L.  However, once the selection is known to have been
  262.       --  written it can be accessed without protection.  This happens
  263.       --  after Self has updated it itself using information from a suspended
  264.       --  Caller, or after Caller has updated it and awakened Self.
  265.  
  266.       Call : Entry_Call_Link;
  267.       --  The entry call that has been accepted by this task.
  268.       --  Protection: Self.L.  Self will modify this field
  269.       --  when Self.Accepting is False, and will not need the mutex to do so.
  270.       --  Once a task sets Stage=Completing, no other task can access this
  271.       --  field.
  272.  
  273.       --  The following fields are used to manage the task's life cycle.
  274.  
  275.       Activator : ATCB_Ptr;
  276.       --  The task that created this task, either by declaring it as a task
  277.       --  object or by executing a task allocator.
  278.       --  Protection: Set by Activator before Self is activated, and
  279.       --  read after Self is activated.
  280.  
  281.       Parent : ATCB_Ptr;
  282.       Master_of_Task : Master_ID;
  283.       --  The task executing the master of this task, and the ID of this task's
  284.       --  master (unique only among masters currently active within Parent).
  285.       --  Protection: Set by Activator before Self is activated, and
  286.       --  read after Self is activated.
  287.  
  288.       Master_Within : Master_ID;
  289.       --  The ID of the master currently executing within this task; that is,
  290.       --  the most deeply nested currently active master.
  291.       --  Protection: Only written by Self, and only read by Self or by
  292.       --  dependents when Self is attempting to exit a master.  Since Self
  293.       --  will not write this field until the master is complete, the
  294.       --  synchronization should be adequate to prevent races.
  295.  
  296.       Activation_Count : Integer;
  297.       --  This is the number of tasks that this task is activating, i.e. the
  298.       --  children that have started activation but have not completed it.
  299.       --  Protection: Self.L and Created.L.  Both mutexes must be locked,
  300.       --  since Self.Activation_Count and Created.Stage must be synchronized.
  301.  
  302.       Awake_Count : Integer;
  303.       --  Number of tasks dependent on this task (including this task) that are
  304.       --  still "awake": not terminated and not waiting on a terminate
  305.       --  alternative.
  306.       --  Protection: Self.L.  Parent.L must also be locked when this is
  307.       --  updated, so that it can be synchronized with
  308.       --  Parent.Awaited_Dependent_Count, except under special circumstances
  309.       --  where we know that the two can be out of sync without allowing the
  310.       --  parent to terminate before its dependents.
  311.  
  312.       Awaited_Dependent_Count : Integer;
  313.       --  This is the awake count of a master being completed by this task.
  314.       --  Protection: Self.L.  Dependent.L must also be locked so that
  315.       --  this field and Dependent.Awake_Count can be synchronized, except
  316.       --  under special circumstances where we know that the two can be out
  317.       --  of sync without allowing the parent to terminate before its
  318.       --  dependents.
  319.  
  320.       Terminating_Dependent_Count : Integer;
  321.       --  This is the count of tasks dependent on a master being completed by
  322.       --  this task which are waiting on a terminate alternative.  Only valid
  323.       --  when there none of the dependents are awake.
  324.       --  Protection: Self.L.
  325.  
  326.       Pending_Priority_Change : Boolean;
  327.       --  Flag to indicate pending priority change (for dynamic priorities
  328.       --  package). The base priority is updated on the next abortion
  329.       --  completion point (aka. synchronization point).
  330.       --  Protection: Self.L.
  331.  
  332.       Pending_Action : Boolean;
  333.       --  Unified flag indicating pending action on abortion completion
  334.       --  point (aka. synchronization point). Currently set if:
  335.       --  . Pending_Priority_Change is set or
  336.       --  . Pending_ATC_Level is changed.
  337.       --  Protection: Self.L.
  338.  
  339.       Pending_ATC_Level : ATC_Level_Base;
  340.       --  The ATC level to which this task is currently being aborted.
  341.       --  Protection: Self.L.
  342.  
  343.       ATC_Nesting_Level : ATC_Level;
  344.       --  The dynamic level of ATC nesting (currently executing nested
  345.       --  asynchronous select statements) in this task.
  346.       --  Protection: This is only used by Self.  However, decrementing it
  347.       --  in effect deallocates an Entry_Calls component, and care must be
  348.       --  taken that all references to that component are eliminated before
  349.       --  doing the decrement.  This in turn will probably required locking
  350.       --  a protected object (for a protected entry call) or the Acceptor's
  351.       --  lock (for a task entry call).  However, ATC_Nesting_Level itself can
  352.       --  be accessed without a lock.
  353.  
  354.       Deferral_Level : Natural;
  355.       --  This is the number of times that Defer_Abortion has been called by
  356.       --  this task without a matching Undefer_Abortion call.  Abortion is
  357.       --  only allowed when this zero.
  358.       --  Protection: Only updated by Self; access assumed to be atomic.
  359.  
  360.       Elaborated : Access_Boolean;
  361.       --  Pointer to a flag indicating that this task's body has been
  362.       --  elaborated.  The flag is created and managed by the
  363.       --  compiler-generated code.
  364.       --  Protection: The field itself is only accessed by Activator.  The flag
  365.       --  that it points to is updated by Master and read by Activator; access
  366.       --  is assumed to be atomic.
  367.  
  368.       Stage : Task_Stage;
  369.       --  The general stage of the task in it's life cycle.
  370.       --  Protection: Self.L.
  371.  
  372.       --  beginning of flags
  373.  
  374.       Cancel_Was_Successful : Boolean;
  375.       --  This indicates that the last attempt to cancel an entry call was
  376.       --  successful.  It needs to be accurate between a call to
  377.       --  *Cancel_*_Entry_Call and the following call to Complete_*_Entry_Call.
  378.       --  These calls cannot be nested; that is, there can be no intervening
  379.       --  *Cancel_*_Entry_Call, so this single field is adequate.
  380.       --  Protection: Accessed only by Self.
  381.  
  382.       Accepting : Accepting_State;
  383.       --  The ability of this task to accept an entry call.
  384.       --  Protection: Self.L.
  385.  
  386.       Aborting : Boolean;
  387.       --  Self is in the process of aborting. While set, prevents multiple
  388.       --  abortion signals from being sent by different aborter while abortion
  389.       --  is acted upon. This is essential since an aborter which calls
  390.       --  Abort_To_Level could set the Pending_ATC_Level to yet a lower level
  391.       --  (than the current level), may be preempted and would send the
  392.       --  abortion signal when resuming execution. At this point, the abortee
  393.       --  may have completed abortion to the proper level such that the
  394.       --  signal (and resulting abortion exception) are not handled any more.
  395.       --  In other words, the flag prevents a race between multiple aborters
  396.       --  and the abortee.
  397.       --  Protection: Self.L.
  398.  
  399.       Suspended_Abortably : Boolean;
  400.       --  Task is suspended with (low-level) abortion deferred, but is
  401.       --  abortable.  This means that the task must be awakened to perform
  402.       --  its own abortion.
  403.       --  Protection: Self.L.
  404.  
  405.       --  end of flags
  406.  
  407.       Entry_Calls : Entry_Call_Array;
  408.       --  An array of Ada 9X entry calls.
  409.       --  Protection: The elements of this array are on entry call queues
  410.       --  associated with protected objects or task entries, and are protected
  411.       --  by the protected object lock or Acceptor.L, respectively.
  412.  
  413.       Entry_Queues : Entry_Queue_Array (1 .. Entry_Num);
  414.       --  An array of task entry queues.
  415.       --  Protection: Self.L.  Once a task has set Self.Stage to Completing, it
  416.       --  has exclusive access to this field.
  417.  
  418.       Aborter_Link : ATCB_Ptr;
  419.       --  Link to the list of tasks which tries to abort this task but
  420.       --  blocked by another aborter who has already been aborting the task.
  421.  
  422.       Terminate_Alternative : Boolean;
  423.       --  Task is accepting Select with Terminate Alternative.
  424.  
  425.    end record;
  426.  
  427.    --  The following record holds the information used to initialize a task
  428.  
  429.  
  430.    type ATCB_Init is record
  431.       Task_Entry_Point : Task_Procedure_Access;
  432.       Task_Arg         : System.Address;
  433.       Stack_Size       : Size_Type;
  434.       Activator        : ATCB_Ptr;
  435.       Parent           : ATCB_Ptr;
  436.       Master_of_Task   : Master_ID;
  437.       Elaborated       : Access_Boolean;
  438.       Entry_Num        : Task_Entry_Index;
  439.       Priority         : System.Priority;
  440.    end record;
  441.  
  442.    procedure Vulnerable_Complete_Activation
  443.      (T : ATCB_Ptr;
  444.       Completed : Boolean);
  445.    --  Completes the activation by signaling its children.
  446.    --  Completed indicates a call when the task has completed.
  447.    --  Does not defer abortion (unlike Complete_Activation).
  448.  
  449.  
  450.    procedure Check_Exception;
  451.    --  Raises an exception pending on Self.
  452.    --  Used to delay exceptions until abortion is undeferred.
  453.  
  454. -------------------------------------------
  455.  
  456.    --  Rendezvous related routines
  457.    procedure Close_Entries (Target : Task_ID);
  458.    --  Close entries, purge entry queues (called by Task_Stages.Complete)
  459.    --  T.Stage must be Completing before this is called.
  460.  
  461.    procedure Complete_on_Sync_Point (T : Task_ID);
  462.    --  If a task is suspended on an accept, select, or entry call
  463.    --  (but not yet *in* rendezvous) then complete the task.
  464.  
  465.    procedure Reset_Priority
  466.      (Acceptor_Prev_Priority : Rendezvous_Priority;
  467.       Acceptor               : Task_ID);
  468.    pragma Inline (Reset_Priority);
  469.    --  Reset the priority of a task completing an accept statement to
  470.    --  the value it had before the call.
  471.  
  472.    procedure Terminate_Alternative;
  473.    --  Called when terminate alternative is selected.
  474.    --  Waits for the parent to terminate the task
  475.    --  or a caller to select an accept alternative.
  476.    --  Assumes that abortion is deferred when called.
  477.  
  478.    procedure Complete (Target : Task_ID);
  479.    --  Complete task and act on pending abortion.
  480.  
  481.  
  482.    --  Task_Stage Related routines.
  483.  
  484.    procedure Make_Independent;
  485.    --  Remove a task from the master hierarchy.  This includes setting the
  486.    --  master ID to zero (no master) and removing the task from the
  487.    --  All_Tasks_List (which is used to search for masters and dependents).
  488.    --  No master will wait on the termination of an independent task;
  489.    --  such tasks may still be running when the program terminates, at which
  490.    --  point they will be killed by the underlying operating system.
  491.    --  This is a dangerous operation, and should only be used on tasks
  492.    --  that require no finalization.  Independent tasks are intended only
  493.    --  for internal use by the GNARL, to prevent such internal tasks from
  494.    --  preventing a user task from terminating.
  495.  
  496.  
  497.    --  Task Abortion related routines
  498.  
  499.    procedure Abort_To_Level (Target : Task_ID; L : ATC_Level);
  500.    --  Abort a task to a specified ATC level.
  501.  
  502.    procedure Abort_Handler (Context : Task_Primitives.Pre_Call_State);
  503.    --  Handler to be installed at initialization; it is invoked by a task
  504.    --  when it is the target of an Abort_Task low-level operation.
  505.  
  506.    procedure Abort_Dependents (Abortee : Task_ID);
  507.    --  Propagate the abortion of a parent into its children.
  508.  
  509.    procedure Remove_From_All_Tasks_List
  510.       (Source : Utilities.ATCB_Ptr; Result : out Boolean);
  511.    --  Remove an entry from the All_Tasks_List.
  512.  
  513.  
  514. end System.Tasking.Utilities;
  515.